package org.zoomdev.zoom.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.common.utils.Classes;
import org.zoomdev.zoom.ioc.Ioc;
import org.zoomdev.zoom.ioc.IocTypeKey;
import org.zoomdev.zoom.ioc.impl.builder.IocBuilder;
import org.zoomdev.zoom.web.action.ActionHandler;
import org.zoomdev.zoom.web.handlers.NotFoundFilterHandler;
import org.zoomdev.zoom.web.modules.CoreWebModule;
import org.zoomdev.zoom.web.router.Router;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * web配置:
 * <p>
 * zoom.config.name
 * zoom.scan.modules
 * zoom.scan.filter
 */
public final class WebService implements Filter {


    private static final Logger log = LoggerFactory.getLogger(CoreWebModule.class);

    private Ioc ioc;

    private Router router;
    private NotFoundFilterHandler notFoundHandler;

    private ExceptionHandler exceptionHandler;

    @Override
    public void init(FilterConfig config) throws ServletException {
        try {
            Map<String, String> param = new HashMap<>();
            Enumeration<String> enumeration = config.getInitParameterNames();
            while (enumeration.hasMoreElements()) {
                String key = enumeration.nextElement();
                param.put(key, config.getInitParameter(key));
            }
            IocBuilder builder = new IocBuilder();
            builder.createParameters(param);


            builder.put(new IocTypeKey(WebService.class), this)
                    .put(new IocTypeKey(Filter.class), this);
            Ioc ioc = builder.build();
            this.ioc = ioc;
            this.router = ioc.fetch(Router.class);
            this.notFoundHandler = ioc.fetch(NotFoundFilterHandler.class);
            this.exceptionHandler = ioc.fetch(ExceptionHandler.class);

            log.info("=========Zoom Web Server 启动成功================");

        } catch (Throwable e) {
            log.error("=========Zoom Web Server 启动失敗================", e);
            if (e instanceof ServletException) {
                throw e;
            }
            throw new ServletException(e);
        }


    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        try {
            ActionHandler handler = router.match(request);
            if (handler == null) {
                notFoundHandler.handle(request, response, chain);
                return;
            }
            handler.handle(request, response);
        } catch (Throwable e) {
            exceptionHandler.handle(request, response, e);
        }
    }

    @Override
    public void destroy() {
        Classes.destroy(ioc);
    }


    public Ioc getIoc() {
        return ioc;
    }


}
